package com.avic.modules.log.service.impl;


import com.avic.common.service.impl.BaseServiceImpl;
import com.avic.common.utils.QueryHelpPlus;
import com.avic.dozer.service.IGenerator;
import com.avic.modules.log.domain.Log;
import com.avic.modules.log.domain.vo.LogEnumeration;
import com.avic.modules.log.domain.vo.LogVo;
import com.avic.modules.log.service.LogsService;
import com.avic.modules.log.service.dto.LogDto;
import com.avic.modules.log.service.dto.LogQueryCriteria;
import com.avic.modules.log.service.mapper.LogsMapper;
import com.avic.modules.system.domain.Dept;
import com.avic.modules.system.domain.User;
import com.avic.modules.system.service.mapper.DeptMapper;
import com.avic.modules.system.service.mapper.SysUserMapper;
import com.avic.utils.*;
import com.github.pagehelper.PageInfo;
import lombok.AllArgsConstructor;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

@Service(value = "logsService")
@AllArgsConstructor
@Transactional(propagation = Propagation.SUPPORTS, readOnly = true, rollbackFor = Exception.class)
public class LogsServiceImpl extends BaseServiceImpl
        <LogsMapper, Log> implements LogsService {
    private final IGenerator generator;
    private final DeptMapper deptMapper;
    private final LogsMapper logMapper;
    private final SysUserMapper sysUserMapper;

    /**
     * 查询操作日志分页
     * @param criteria 条件
     * @param pageable 分页参数
     * @return
     */
    @Override
    public Map<String, Object> queryAll(LogQueryCriteria criteria, Pageable pageable) {
        getPage(pageable);
        PageInfo<Log> page = new PageInfo<>(queryAll(criteria));
        List<LogDto> convert = generator.convert(page.getList(), LogDto.class);
        Map<String, Object> map = new LinkedHashMap<>(2);
        map.put("content", convert);
        map.put("totalElements", page.getTotal());
        return map;
    }

    /**
     * 查询操作日志不分页
     * @param criteria 条件参数
     * @return
     */
    @Override
    public List<Log> queryAll(LogQueryCriteria criteria) {

        return baseMapper.selectList(QueryHelpPlus.getPredicate(Log.class, criteria));
    }

    @Override
    public List<Log> queryAlls(LogQueryCriteria criteria, Pageable pageable) {
        String order = "id desc";
        getPageSize(pageable,order);
        return baseMapper.selectList(QueryHelpPlus.getPredicate(Log.class, criteria));
    }

    @Override
    @Transactional(propagation = Propagation.REQUIRES_NEW ,rollbackFor = Exception.class)
    public void save(LogVo logVo) {
        long start = System.nanoTime();
        User user = sysUserMapper.selectById(SecurityUtils.getUserId());
        Log log = new Log();

        // 获取浏览器信息
        RedisUtils redisUtils = BeanUtil.getBean(RedisUtils.class);
        String userAgent = redisUtils.get(user.getUsername()).toString();
        log.setBrowser(userAgent);

        // 查找部门信息
        Dept dept = deptMapper.selectById(user.getDeptId());
        log.setDeptName(dept.getName());
        log.setUid(user.getId());
        log.setDeptId(user.getDeptId());
        log.setUsername(user.getUsername());

        Timestamp timestamp = new Timestamp(System.currentTimeMillis());
        // 获取ip地址
        String ip = StringUtils.getIp(RequestHolder.getHttpServletRequest());
        log.setRequestIp(ip);
        log.setAddress(StringUtils.getRegionInfo(log.getRequestIp()));
        log.setCreateTime(timestamp);
        long finish = System.nanoTime();

        long time = (finish - start)/100000;
        log.setTime(time);
        log.setLogType(logVo.getAction());
        String string = timestamp.toString();
        String substring = string.substring(0, string.length() - 4);
        String name = "[" + user.getUsername() + "]" + " " + substring + " " + logVo.getBehavior();
        long sum = 0;
        String information = logVo.getInformation();
        if(information!=null){
            log.setExceptionDetail(information);
            sum = information.length();
        }
        log.setDescription(name);
        if(sum!=2){
            logMapper.insert(log);
        }
    }

    @Transactional(propagation = Propagation.REQUIRES_NEW,rollbackFor = Exception.class)
    public void sysAdminSave(LogVo logVo) {
        long start = System.nanoTime();
        Log log = new Log();
        log.setBrowser("sysAdmin");
        log.setDeptName("sysAdmin");
        log.setUsername("sysAdmin");
        Timestamp timestamp = new Timestamp(System.currentTimeMillis());
        log.setCreateTime(timestamp);
        log.setLogType(logVo.getAction());
        String name = "[ sysAdmin ] " + timestamp + " " + logVo.getBehavior();
        log.setDescription(name);
        logMapper.insert(log);
    }

    @Override
    public void download(List<LogDto> all, HttpServletResponse response) throws IOException {
        List<Map<String, Object>> list = new ArrayList<>();
        long sum = 1;
        for(LogDto log: all) {
            Map<String, Object> map = new LinkedHashMap<>();
            map.put("序号", sum);
            if(log.getCreateTime()==null){
                map.put("操作日期",log.getCreateTime());
            }else {
                String s = log.getCreateTime().toString();
                String substring = s.substring(0, s.length() - 2);
                map.put("操作日期",substring);
            }
            map.put("用户", log.getUsername());
            map.put("动作", log.getLogType());
            String exceptionDetail = log.getExceptionDetail();
            if(exceptionDetail==null){
                map.put("内容", log.getDescription());
            }else {
                map.put("内容", log.getDescription()+exceptionDetail);
            }

            map.put("IP地址", log.getRequestIp());
            map.put("部门", log.getDeptName());
            sum ++;
            list.add(map);
        }
        String name = "[导出]了"+ "[操作日志]";
        LogVo logVo = new LogVo();
        logVo.setAction(LogEnumeration.LEADING_OUT.getMessage());
        logVo.setBehavior(name);
        save(logVo);
        FileUtil.downloadExcel(list, response);
    }

    @Override
    public Object queryAllByUser(LogQueryCriteria criteria, Pageable pageable) {
        criteria.setBlurry(SecurityUtils.getUsername());
        getPage(pageable);
        PageInfo<Log> page = new PageInfo<>(queryAll(criteria));
        Map<String, Object> map = new LinkedHashMap<>(2);
        map.put("content", generator.convert(page.getList(), LogDto.class));
        map.put("totalElements", page.getTotal());
        return map;
    }


}
